package com.vsoft.sms_cm;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.mongodb.BulkWriteOperation;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.MongoException;
import com.mongodb.util.JSON;
import com.vsoft.framework.core.BaseException;
public class Mongodb {
	private static String vName = Mongodb.class.getName();
	static String IP="IP",PORT="PORT";
	static int DEFAULTPORT=27017;
	private static Connection conn = null;  
	private Statement statement = null;  
	private ResultSet rs = null;  
	private PreparedStatement ps=null; 
	Logger vLogger = Logger.getLogger(Mongodb.class);
	private final  boolean jsonFlag/*,bulkFlag*/;
	/*private final String stringClassName = "class java.lang.String",hashMapClassName= "class java.util.HashMap";*/
	//BulkWriteOperation bulkBuilder=null;
	public void  init(HashMap<String,String> connString)
	{
		
	}
	public Mongodb(boolean JsonFlag/*,boolean BulkFlag*/)
	{
		/*bulkFlag =BulkFlag;	*/
		jsonFlag=JsonFlag;
		
//		this.setJsonFlag(jsonFlag);
//		this.setBulkFlag(bulkFlag);
	}
/*	private BulkWriteOperation genBulkBuilder(DBCollection coll)
	{
		BulkWriteOperation bulkBuilder;
		if(bulkFlag)
			bulkBuilder = coll.initializeUnorderedBulkOperation();
		else
			bulkBuilder	=	null;
		return bulkBuilder;
		
	}*/

	//新的获取mongodb连接方法
	public MongoClient getMongoClient(HashMap<String,String> connString) throws BaseException
	{
		String ip 		= 	connString.get(IP);
		String port 	= 	connString.get(PORT);
		int DBport		= 	DEFAULTPORT;
		if (!this.isSTRNull(port))
			DBport		=	Integer.parseInt(port);
		
		MongoClient m	=	null;
		try {
			m = new MongoClient(ip,DBport);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new BaseException(vName +"-001","获取mongodb为："+IP+"的连接出错！");
		}
		return m;
	}
	//get mongodb's db
	public DB getDB(Mongo m,String dbName) throws Exception
	{
		if( this.isSTRNull(dbName))
			throw new Exception ("dbName is null");
		if(m==null)
			throw new Exception ("Mongodb is null");
		DB db = m.getDB(dbName );
		//DB db = m.getDB( "mydb" );
		return db;
	}
	public boolean isSTRNull(String str)
	{
		if (str==null ||str.trim().equals(""))
			return true;
		else
			return false;
	}
	//insert a row into a collection 
//	====================class java.util.HashMap
//			====================class java.lang.String

//	private void insertOneIntoColl(DB db,String collectionName, Object  Data ,String dataClassName) throws BaseException
//	{
//		try{
//			DBCollection coll = db.getCollection(collectionName);
//			String objectClass = Data.getClass().toString();
//			BasicDBObject doc = new BasicDBObject();
//			if(objectClass.equals(stringClassName))
//				coll.insert(this.genDoc((String) Data));
//			else
//				coll.insert(this.genDoc((HashMap<String,Object>)Data));
//				
//			
//
//			//doc = (BasicDBObject) hData;
//			if (bulkFlag)
//				
//			coll.insert(doc);
//			
//		}
//		catch(Exception ex)
//		{
//			ex.printStackTrace();
//			throw new BaseException(vName +"-004","插入mongodb 数据出错：collectionName:"+collectionName+"\n exception:  "+ex);
//		}
//	}
//	private BasicDBObject genDoc(HashMap<String, Object>  hData)
//	{
//		BasicDBObject doc = new BasicDBObject();
//		for(String key:hData.keySet())
//		{
//			//vLogger.info(key+":"+hData.get(key));
//			doc.put(key, hData.get(key));
//		}
//		return doc;
//	}
//	private DBObject genDoc(String json)
//	{
//		DBObject doc = null;
//		try
//		{
//			doc = (DBObject)JSON.parse(json);
//		}
//		catch(Exception ex)
//		{
//			ex.printStackTrace();
//			vLogger.info("================json parse出错不退出！");
//			return null;
//		}
//		return doc;
//	}
	//insert a row into a collection 
	public void insertCollection(DB db,DBCollection coll,HashMap<String, Object>  hData/*,BulkWriteOperation bulkBuilder */) throws BaseException
	{
		try{
			//DBCollection coll = db.getCollection(collectionName);
//			for(Map.Entry <String,   Object>   entry   :   hData.entrySet())   
//			{ 
//				//System.out.println(entry.getKey()   +   "   -->   "   +   entry.getValue()); 
//				String key =entry.getKey();
//				String value =(String)entry.getValue();
//				
//				BasicDBObject doc = new BasicDBObject();
//				doc.put(key, value);
//			}
			BasicDBObject doc = new BasicDBObject();
			//doc.putAll(hData);
			for(String key:hData.keySet())
			{
				//vLogger.info(key+":"+hData.get(key));
				doc.put(key, hData.get(key));
			}
			//doc = (BasicDBObject) hData;
/*			if (bulkFlag)
				bulkBuilder.insert(doc);
			else*/
				coll.insert(doc);
			
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
			throw new BaseException(vName +"-004","插入mongodb 数据出错：collectionName:"+coll.getName()+"\n exception:  "+ex);
		}
	}
	//insert a row into a collection Json
	public void insertCollectionJson(DB db,DBCollection coll,String json/*,BulkWriteOperation bulkBuilder*/ ) throws BaseException
	{
		try{
			//DBCollection coll = db.getCollection(collectionName);
			DBObject doc =null;
			try
			{
				doc = (DBObject)JSON.parse(json);
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
				vLogger.info("================json parse出错不退出！");
				return;
			}

/*			if (bulkFlag)
				bulkBuilder.insert(doc);
			else*/
				coll.insert(doc);
			
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
			throw new BaseException(vName +"-006","插入mongodb json 数据出错：collectionName:"+coll.getName()+"\n exception:  "+ex);
		}
	}
//	public void setBulkFlag(boolean flag)
//	{
//		//bulkFlag =flag;
//	}
//	
//	public void setJsonFlag(boolean flag)
//	{
//		jsonFlag =flag;
//	}
	public long queryAndInsMDB(DB db,String collectionName,Connection conn,String sql,Object[] params) throws BaseException
	{
		long cnt=0;
		
		try 
		{
			ps = conn.prepareStatement(sql);
			ps.setFetchSize(1000);
			if(params!=null)
			{
				for(int i=0;i<params.length;i++)
				{     ps.setObject(i+1, params[i]);     }    
			}
			long start_time		=	System.currentTimeMillis();
			vLogger.info("---------------start-------------"+start_time);
			rs=ps.executeQuery(); 
			long batch_time=System.currentTimeMillis();
			vLogger.info("---------------query time-------------"+(batch_time-start_time));
			String[] columnName = this.getResultSetMetaData(rs);
			batch_time=System.currentTimeMillis();
			vLogger.info("---------------getResultSetMetaData time-------------"+(batch_time-start_time));
			
//			for(int i=0;i<50000;i++)
//			{
//				HashMap<String,Object>data=new HashMap<String,Object>();
//				data.put("key", "value");
//				this.insertCollection(db, collectionName, data);
//			}
			DBCollection coll = db.getCollection(collectionName);
			/*BulkWriteOperation bulkBuilder=this.genBulkBuilder(coll);*/
			int mod=10000;

			while(rs.next())
			{
				if(cnt%mod==0)
				{
					batch_time=System.currentTimeMillis();
					vLogger.info(cnt+"record---------------insert into mongodb "+mod/10000+"w's time-------------"+(batch_time-start_time));
					start_time		=	System.currentTimeMillis();
/*					if(bulkFlag & cnt>0)
					{
						bulkBuilder.execute();
						bulkBuilder=this.genBulkBuilder(coll);
					}*/
				}
				
				HashMap<String,Object>data=new HashMap<String,Object>();
				StringBuffer json =new StringBuffer();
				
				json.append("{");
				for(int i=0;i<columnName.length;i++)
				{
					//data.put(columnName[i],rs.getObject(columnName[i]));
					if(!jsonFlag)
						data.put(columnName[i],rs.getString(columnName[i]));
					else
					{
						if(i>0)
							json.append(",");
						json.append("'").append(columnName[i]).append("':'").append(rs.getString(columnName[i])).append("'");						
					}

				}
				json.append("}");
				//
				if(!jsonFlag)
					this.insertCollection(db, coll, data/*,bulkBuilder*/);
				else
					this.insertCollectionJson(db, coll, json.toString()/*,bulkBuilder*/);
				
				cnt++;
			}
/*			if(bulkFlag&cnt%mod>0)
				bulkBuilder.execute();*/
			vLogger.info("================queryAndInsMDB records:"+cnt);

		} 
		catch (SQLException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new BaseException(vName +"-003","查询datbase 数据出错：sql:"+sql+"\n exception:  "+e);	
		} 
		finally
		{
			vLogger.info("=========关闭资源=======");
			
			try {
				rs.close();
				rs = null;
				ps.close();
				ps =null;
				
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new BaseException(vName +"-005","关闭资源出错 \n exception:  "+e);	
			}

		}
		return cnt;

	}
	public String[] getResultSetMetaData(ResultSet rs) throws BaseException
	{
		ResultSetMetaData rsm;
		try {
			rsm = rs.getMetaData();
			int count=rsm.getColumnCount();     
			//存储查询结果的列名     
			String[] strColumns=new String[rsm.getColumnCount()];
			//循环遍历结果集 
			for(int i=1;i<=count;i++ )
			{
			//    //返回构造其实例的 Java 类的完全限定名称 
			//    System.out.print(rsm.getColumnClassName(i)+"\t"); //    
				//获取指定列的 SQL 类型,返回值为int类型 
			//    System.out.print(rsm.getColumnType(i)+"\t"); //    
				//获取指定列的数据库特定的类型名称。 
			//    System.out.print(rsm.getColumnTypeName(i)+"\t"); //    
				//获取指定列的名称。 
			//    System.out.print(rsm.getColumnName(i)+"\t"); //  
			//     * 建议标题通常由 SQL AS 子句来指定。 
			//     * 如果未指定 SQL AS，则从 getColumnLabel 返回的值将和 //     *  getColumnName 方法返回的值相同。 */ 
				//System.out.println("getColumnName:"+rsm.getColumnName(i));
				//System.out.println("getColumnLabel:"+rsm.getColumnLabel(i));
				strColumns[i-1]	=	rsm.getColumnLabel(i);
			}
			//获取用于打印输出和显示的指定列的建议标题。
			return strColumns;
		} 
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new BaseException(vName +"-002","获取datbase resultset的元数据出错："+e);			
		}    //获取查询结果有多少列     
		finally {
			rsm = null;
		}

	}
	////////////////////////////////////////////////////////////////////////////////////////////////////
	//get mongodb 
	@SuppressWarnings("deprecation")
	public Mongo  getMongodb(HashMap<String,String> connString) throws MongoException, UnknownHostException
	{
		String ip 		= connString.get(IP);
		String port 	= connString.get(PORT);
		int DBport		= DEFAULTPORT;
		if (!this.isSTRNull(port))
			DBport		=	Integer.parseInt(port);
		//Mongo m = new Mongo( ip , 27017 );
		
		Mongo m = new Mongo( ip , DBport );
		return m;
	}
	//public 
	public void insertSample(DB db,String collection,long count) throws Exception
	{
		try{
			DBCollection coll = db.getCollection(collection);
			for (long i=0;i<count;i++)
			{
				BasicDBObject doc = new BasicDBObject();

		        doc.put("name", "MongoDB");
		        doc.put("type", "database");
		        doc.put("count", "count--"+i);

		        BasicDBObject info = new BasicDBObject();

		        info.put("x", 203);
		        info.put("y", 102);

		        doc.put("info", info);

		        coll.insert(doc);
			}
			
		}
		catch(Exception ex)
		{
			throw new Exception("insert sample data error"+ex);
		}
	}
}
